﻿using StarsAdmin.Core.DI;

namespace StarsAdmin.Core.Cache
{
    public interface ICacheService : IDependency
    {
        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        void Set(string key, object value, int expire = default);

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        Task SetAsync(string key, object value, int expire = default);

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        public void Set(long userId, string type, object value, int expire = default);

        /// <summary>
        /// 添加数据到本地缓存
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">缓存值</param>
        /// <param name="expire">过期时间(分钟)</param>
        Task SetAsync(long userId, string type, object value, int expire = default);

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <returns></returns>
        T Get<T>(long userId, string type);

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <returns></returns>
        Task<T> GetAsync<T>(long userId, string type);

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns></returns>
        public T Get<T>(string key);

        /// <summary>
        /// 获得本地缓存中的数据
        /// </summary>
        /// <typeparam name="T">返回值类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns></returns>
        Task<T> GetAsync<T>(string key);

        /// <summary>
        /// 尝试获得指定键的值
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">获得的返回值</param>
        /// <returns></returns>
        bool TryGetValue(string key, out object? value);

        /// <summary>
        /// 尝试获得指定键的值
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">获得的返回值</param>
        /// <returns></returns>
        Task<bool> TryGetValueAsync(string key, out object? value);

        /// <summary>
        /// 异步获取或者设置指定键的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="func">回调函数</param>
        /// <param name="expire">过期时间(分钟)</param>
        /// <returns></returns>
        Task<T> GetOrSetAsync<T>(string key, Func<Task<T>> func, int expire = default);

        /// <summary>
        /// 异步获取或者设置指定键的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="userId">用户Id</param>
        /// <param name="func">回调函数</param>
        /// <param name="expire">过期时间(分钟)</param>
        /// <returns></returns>
        Task<T> GetOrSetAsync<T>(string key, long userId, Func<Task<T>> func, int expire = default);

        /// <summary>
        /// 异步获取或者设置指定键的值
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key">缓存键</param>
        /// <param name="func">回调函数</param>
        /// <param name="expire">过期时间(分钟)</param>
        /// <returns></returns>
        T GetOrSet<T>(string key, Func<T> func, int expire = default);

        /// <summary>
        /// 验证指定键是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns></returns>
        bool Validate(string key);

        /// <summary>
        /// 验证指定键是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns></returns>
        Task<bool> ValidateAsync(string key);

        /// <summary>
        ///  验证数据是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        bool Validate(string key, object value);

        /// <summary>
        ///  验证数据是否存在
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        Task<bool> ValidateAsync(string key, object value);

        /// <summary>
        /// 验证数据是否存在
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        bool Validate(long userId, string type, object value);

        /// <summary>
        /// 验证数据是否存在
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        /// <param name="value">需要验证的数据</param>
        /// <returns></returns>
        Task<bool> ValidateAsync(long userId, string type, object value);

        /// <summary>
        /// 移除指定键的数据
        /// </summary>
        /// <param name="key">缓存键</param>
        void Remove(string key);

        /// <summary>
        /// 移除指定键的数据
        /// </summary>
        /// <param name="key">缓存键</param>
        Task RemoveAsync(string key);

        /// <summary>
        /// 移除指定的数据
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        void Remove(long userId, string type);

        /// <summary>
        /// 移除指定的数据
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <param name="type">数据类别</param>
        Task RemoveAsync(long userId, string type);
    }
}